import json
import re

from config import *
from socket import *
from threading import Thread

ADDR = (HOST, PORT)


def connect_frame(env):
    """
        与应用服务端建立通信
    :param env: 要发送给应用服务端的报文数据
    :return: 应用服务端的响应数据
    """
    s = socket()
    try:
        s.connect((frame_ip, frame_port))
    except Exception as e:
        print(e)
        return
    # 将请求字典转换为json字符串数据发送
    data = json.dumps(env)
    s.send(data.encode())
    # 接收webframe数据,接收json
    data = s.recv(4096 * 100).decode()
    # 关闭连接
    s.close()
    # 返回数据字典
    return json.loads(data)


class HttpServer:
    """
        封装httpserver基本功能
    """

    def __init__(self, address):
        self.port = None
        self.ip = None
        self.sockfd = None
        self.address = address
        self.create_socket()
        self.bind()

    def create_socket(self):
        """
            创建套接字
        :return:
        """
        self.sockfd = socket()
        self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, DEBUG)

    def bind(self):
        """
            绑定地址
        :return:
        """
        self.sockfd.bind(ADDR)
        self.ip = self.address[0]
        self.port = self.address[1]

    def serve_forever(self):
        """
            启动服务器
        :return:
        """
        self.sockfd.listen(5)
        print("Listen the port%d ..." % self.port)
        while True:
            # 接收客户端连接
            c, addr = self.sockfd.accept()
            print("收到客户端连接:", addr)
            client = Thread(target=self.handle, args=(c,))
            client.daemon = True
            client.start()

    def handle(self, connfd):
        """
            处理具体的客户端请求
        :param connfd:
        :return:
        """
        request = connfd.recv(4096).decode()
        pattern = r"(?P<method>[A-Z]+)\s+(?P<info>/\S*)"
        try:
            env = re.match(pattern, request).groupdict()
        except:
            connfd.close()
            return
        else:
            data = connect_frame(env)
            if data:
                self.response(connfd, data)

    def response(self, connfd, data):
        """
            将数据整理为响应格式发送给浏览器
        :param connfd:
        :param data:
        :return:
        """
        if data['status'] == '200':
            responseHeaders = 'HTTP/1.1 200 OK\r\n'
            responseHeaders += 'Content-Type:text/html\r\n'
            responseHeaders += '\r\n'
            responseBody = data['data']
        elif data['status'] == '404':
            responseHeaders = 'HTTP/1.1 404 Not Found\r\n'
            responseHeaders += 'Content-Type:text/html\r\n'
            responseHeaders += '\r\n'
            responseBody = data['data']
        elif data['status'] == '500':
            pass

        response_data = responseHeaders + responseBody
        connfd.send(response_data.encode())
        connfd.close()


if __name__ == "__main__":
    server = HttpServer(ADDR)
    server.serve_forever()
